// File: jmcomic-core/src/main/java/dev/jukomu/common/base/registry/ShutdownHookManager.java
package dev.jukomu.common.base.registry;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 对应Python的AtexitRegistry，用于管理JVM关闭钩子（Shutdown Hooks）。
 * 提供注册、注销和清理JVM关闭时执行的任务。
 */
public class ShutdownHookManager {

    // 存储已注册的钩子，key为钩子名称，value为线程实例
    private static final Map<String, Thread> registeredHooks = new ConcurrentHashMap<>();
    private static final AtomicInteger hookCount = new AtomicInteger(0); // 跟踪注册的钩子数量

    /**
     * 注册一个在JVM关闭时执行的任务。
     *
     * @param task     要执行的任务（Runnable）
     * @param hookName 钩子的唯一名称，如果已存在同名钩子，则旧的会被覆盖（注销并重新注册）。
     */
    public static void register(Runnable task, String hookName) {
        // 如果已存在同名钩子，先注销它
        unregister(hookName);

        Thread hookThread = new Thread(task, "ShutdownHook-" + hookName);
        registeredHooks.put(hookName, hookThread);
        Runtime.getRuntime().addShutdownHook(hookThread);
        hookCount.incrementAndGet();
    }

    /**
     * 注销指定名称的关闭钩子。
     *
     * @param hookName 要注销的钩子名称
     * @return 如果成功注销返回 true，否则返回 false（例如钩子不存在或已在执行中）
     */
    public static boolean unregister(String hookName) {
        Thread hookThread = registeredHooks.remove(hookName);
        if (hookThread != null) {
            try {
                // removeShutdownHook可能在钩子已经启动或已经完成时失败
                boolean removed = Runtime.getRuntime().removeShutdownHook(hookThread);
                if (removed) {
                    hookCount.decrementAndGet();
                }
                return removed;
            } catch (IllegalStateException e) {
                // JVM正在关闭，或者钩子正在运行
                System.err.println("Failed to unregister shutdown hook " + hookName + ": " + e.getMessage());
                return false;
            }
        }
        return false;
    }

    /**
     * 清理所有已注册的关闭钩子。
     * 注意：此操作应谨慎使用，可能导致重要资源未被释放。
     */
    public static void clear() {
        // 获取所有已注册钩子的名称集合的副本
        Set<String> hookNames = registeredHooks.keySet();
        for (String hookName : hookNames) {
            unregister(hookName);
        }
        // Double check count, should be 0 after clear
        if (hookCount.get() != 0) {
            System.err.println("Warning: ShutdownHookManager.clear() finished, but hookCount is not zero: " + hookCount.get());
        }
    }

    /**
     * 获取当前已注册的关闭钩子数量。
     * 对应Python的atexit_ncallbacks()。
     *
     * @return 钩子数量
     */
    public static int getRegisteredHookCount() {
        return hookCount.get();
    }

    // 私有构造函数，防止实例化
    private ShutdownHookManager() {
    }
}